#include <algorithm/analytical_model/io/json/converter/analytical_model/HeliostatWithGlassPara.h>
#include <algorithm/analytical_model/io/json/converter/shared/utils/Vec2.h>

using namespace solar;

void solar::tag_invoke(const boost::json::value_from_tag& /*unused*/,
                       boost::json::value& json_value,
                       const HeliostatWithGlassPara& heliostat_with_glass_para)
{
    auto refractivity =
        SOLAR_GET_VALUE(HeliostatWithGlassPara, refractivity_, heliostat_with_glass_para);
    auto sigma_glass_up_slope_error = SOLAR_GET_VALUE(
        HeliostatWithGlassPara, sigma_glass_up_slope_error_, heliostat_with_glass_para);
    auto glass_thickness =
        SOLAR_GET_VALUE(HeliostatWithGlassPara, glass_thickness_, heliostat_with_glass_para);
    json_value = {
        {              "refractivity",                                        refractivity},
        {           "glass_thickness",                                     glass_thickness},
        {"sigma_glass_up_slope_error", boost::json::value_from(sigma_glass_up_slope_error)}
    };
}

auto solar::tag_invoke(const boost::json::value_to_tag<HeliostatWithGlassPara>& /*unused*/,
                       const boost::json::value& json_value) -> HeliostatWithGlassPara
{
    const auto* value_ptr = json_value.if_object();
    if (value_ptr == nullptr)
    {
        return {};
    }
    HeliostatWithGlassPara result;
    if (const auto* refractivity_value = value_ptr->if_contains("refractivity");
        refractivity_value != nullptr)
    {
        SOLAR_SET_VALUE(HeliostatWithGlassPara, refractivity_,
                        refractivity_value->to_number<double>(), result)
    }
    if (const auto* glass_thickness_value = value_ptr->if_contains("glass_thickness");
        glass_thickness_value != nullptr)
    {
        SOLAR_SET_VALUE(HeliostatWithGlassPara, refractivity_,
                        glass_thickness_value->to_number<double>(), result)
    }
    if (const auto* sigma_glass_up_slope_error_value =
            value_ptr->if_contains("sigma_glass_up_slope_error");
        sigma_glass_up_slope_error_value != nullptr)
    {
        SOLAR_SET_VALUE(HeliostatWithGlassPara, sigma_glass_up_slope_error_,
                        boost::json::value_to<Vec2>(*sigma_glass_up_slope_error_value), result)
    }
    return result;
}
